Skip to content

fix(oauth): reject incompatible authorization code payloads - #55

Open
jah2488 wants to merge 1 commit into
mainfrom
justinherrick/reject-invalid-oauth-code
Open

jah2488 wants to merge 1 commit into
mainfrom
justinherrick/reject-invalid-oauth-code

Conversation

@jah2488

@jah2488 jah2488 commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Submitting an access or refresh token as an authorization code crashed /oauth-server/token while reading missing authorization state.
The endpoint now returns 400 invalid_grant for incompatible decrypted payloads.

How and why

Validate the token, state and scope before processing the exchange so malformed payloads cannot reach state lookups or scope parsing.
Valid authorization codes continue through the existing client, redirect and PKCE checks.

Testing

On a preview deployment, complete an OAuth flow, then submit its access token as code with grant_type=authorization_code, the same client_id and redirect_uri, and a code_verifier.
Expect 400 invalid_grant; repeat with the refresh token if the client requested offline_access.

@netlify

netlify Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for ntl-mcp ready!

Name Link
🔨 Latest commit b5ae0f6
🔍 Latest deploy log https://app.netlify.com/projects/ntl-mcp/deploys/6af74566ccaaac9ad4874963
😎 Deploy Preview https://deploy-preview-55--ntl-mcp.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for netlify-mcp ready!

Name Link
🔨 Latest commit b5ae0f6
🔍 Latest deploy log https://app.netlify.com/projects/netlify-mcp/deploys/6af74566524f2b81947730ff
😎 Deploy Preview https://deploy-preview-55--netlify-mcp.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for mcp ready!

Name Link
🔨 Latest commit b5ae0f6
🔍 Latest deploy log https://app.netlify.com/projects/mcp/deploys/6af74566a43fdc6218cd5505
😎 Deploy Preview https://deploy-preview-55--mcp.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • Bug Fixes
    • Authorization-code exchanges reject malformed payloads with an invalid_grant response instead of proceeding with invalid token data.
    • Valid PKCE exchanges return the supplied access token and include a refresh token only when the requested scope includes offline_access.

The code-exchange handler now rejects decrypted payloads with invalid access-token, state, or scope fields using invalid_grant. Tests cover invalid payloads and valid PKCE exchanges, including access-token decryption and refresh-token issuance for the offline_access scope.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: seancdavis

Merge Risk: Minimal · previous review adc3c

The handler rejects incompatible authorization-code payloads while preserving valid exchanges with optional scope. No concrete merge-blocking issue is established.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed

Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: rejecting incompatible OAuth authorization code payloads.
Description check Passed The description directly explains the OAuth failure, the invalid_grant response, the validation changes, and the testing approach.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Finishing Touches

🧪 Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.

ℹ️ Recent review info

⚙️ Run configuration

  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 722c1bff-f626-4a51-ad96-46d51e9dba49
📥 Commits

Reviewing files that changed from the base of the PR and between f7f7f06 and adc3cba.

📒 Files selected for processing: 1

  • netlify/functions/mcp-server/auth-flow.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

Included review availability: This review used your included allowance. 8 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour.

@pkg-pr-new

pkg-pr-new Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@netlify/mcp@55

commit: b5ae0f6

@jah2488
jah2488 marked this pull request as ready for review October 2, 2026 16:41
@jah2488
jah2488 force-pushed the justinherrick/reject-invalid-oauth-code branch 3 times, most recently from aecb1ad to f7f7f06 Compare October 5, 2026 19:37
@jah2488

jah2488 commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖🍼 Babysitter.pr 🍼🤖


Rebased onto main (19ed461, #83) with no conflicts and force-pushed with lease. auth-flow tests pass locally (13/13).

Comment on lines +581 to +583
if (typeof accessToken !== 'string' || !accessToken ||
!state || typeof state !== 'object' || Array.isArray(state) ||
(state.scope !== undefined && typeof state.scope !== 'string')) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already use zod in this codebase. Could we kill the as any and as any as CODE_JWE_PAYLOAD above and just use zod for this? We'd get better type safety and DX and this would just work exhaustively.

@jah2488
jah2488 force-pushed the justinherrick/reject-invalid-oauth-code branch 3 times, most recently from 28c5771 to d89b2e0 Compare October 20, 2026 18:56
@jah2488
jah2488 force-pushed the justinherrick/reject-invalid-oauth-code branch 4 times, most recently from b186081 to 9fe08e6 Compare October 26, 2026 16:11
@jah2488
jah2488 force-pushed the justinherrick/reject-invalid-oauth-code branch 4 times, most recently from eb610c2 to 6da541c Compare November 3, 2026 19:39
@jah2488
jah2488 force-pushed the justinherrick/reject-invalid-oauth-code branch from 6da541c to ed37422 Compare November 13, 2026 14:11
@jah2488
jah2488 force-pushed the justinherrick/reject-invalid-oauth-code branch from ed37422 to b5ae0f6 Compare November 13, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants